AWS Systems Manager Automation を使って CFnスタック展開の承認フローを作ってみる
はじめに
以下のような 承認/作成フローを Systems Manager(SSM) オートメーションを使って実現してみます。
大まかな流れは以下のとおり
- 開発者は CFnスタック作成に必要なパラメータを入力して、SSMオートメーションを実行する
- SSMオートメーションは
管理者の承認
ステップに入る - 管理者は SSMオートメーションの内容を確認して、承認する
- SSMオートメーションは
CFnスタック作成
ステップに入る - SSMオートメーションは入力パラメータを元に CFnスタックを作成する
前提知識
SSMドキュメント
多くの人が知っているとおり、 AWS Systems Manager(SSM) でできることはとても多いです。 例えば 「EC2インスタンスに対して特定のコマンドを実行する」Run Command や 「一連のAWSアクションを自動化する」Automation などがあります。
これら SSM 各種機能で実施する定型アクションは AWS Systems Manager(SSM) ドキュメント の構文に従って書かれています。
SSMドキュメントの主な特徴は以下の通り
- YAML もしくは JSONで記述
- 異なるバージョンの作成や比較が可能
- アカウント間の共有が可能
- タイプ が存在して、タイプに合わせた スキーマバージョンを指定する必要がある
- 例えば Run Command の SSMドキュメントは
Command
タイプ。 スキーマバージョンは1.2, 2.0, 2.2
が使用できる - 例えば Automation の SSMドキュメントは
Automation
タイプ。 スキーマバージョンは0.3
を使用する必要がある
- 例えば Run Command の SSMドキュメントは
SSMドキュメントはマネジメントコンソールの AWS Systems Manager > Documents から参照できます。 SSMドキュメントは自身で作成することも可能ですが、 AWSで提供されている SSMドキュメントも豊富にあります。
SSMオートメーション
Systems Manager(SSM) オートメーション は EC2インスタンスや他AWSリソースに関連する 一連の運用作業を自動化するための機能です。
前述の SSMドキュメント(スキーマタイプ Automation
)を活用しています。
Automation で使われる SSMドキュメントは ランブック(runbook) と呼ばれます。
「承認プロセスを含んだ EC2インスタンスの起動/停止フロー」や 「承認プロセスを含んだ CFnスタック作成フロー」などがユースケースです。
もし AWS Config の修復機能を触ったことがある方は、 SSMオートメーションに馴染みがあるかもしれません。 Configルールの「修復アクション」の実態は SSMオートメーションです。
参考: 【AWS Config】EC2インスタンスに特定アプリケーションがインストールされているかチェックして通知する | DevelopersIO
構築
今回の検証で作る必要のあるリソースは以下の 4つです。
- SSMドキュメント: 「承認→CFnスタック作成」フローを記述するために必要です
- SNSトピック: 「承認」ステップで管理者に SNSトピック経由でメール通知を行います
- CFnテンプレート: 「CFnスタック作成」ステップで使うテンプレートです
- IAMロール: SSMオートメーションの実行ロールです
手間の掛からない順番に説明します。
SNSトピック
適宜作成して、管理者へメールが通知されるようにサブスクリプション設定を済ませます。
CFnテンプレート
今回は バケット名/Projectタグをパラメータとした S3バケットを作成するシンプルなテンプレートを使います。
AWSTemplateFormatVersion: '2010-09-09' Parameters: BucketName: Type: String ProjectName: Type: String Resources: S3Bucket: Type: AWS::S3::Bucket Properties: BucketName: !Ref BucketName Tags: - Key: Project Value: !Ref ProjectName
これを S3バケットに格納しておきます。
IAMロール
SSMオートメーションの実行ロールです。以下を行う権限を付与します。
- SNSトピックに送信(Publish)する
- 後述する
aws:approve
アクションで必要な権限です
- 後述する
- CFnスタックを作成する
- 後述する
aws:createStack
アクションで必要な権限です
- 後述する
- S3バケットを作成する
- 同じく
aws:createStack
アクションで必要な権限ですが、 CFnテンプレートで作るリソースに依ります
- 同じく
今回は以下のように CFnテンプレートを使って作成しました。
AWSTemplateFormatVersion: '2010-09-09' Parameters: RoleName: Type: String Default: ssm-automation-role-for-creating-stack Resources: IamRole: Type: AWS::IAM::Role Properties: RoleName: !Ref RoleName Description: "role for ssm automation: create stack" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: "ssm.amazonaws.com" Action: "sts:AssumeRole" Policies: - PolicyName: policy-for-ssm-automation PolicyDocument: Version: "2012-10-17" Statement: # SNSトピックに送信(Publish)する - Sid: approval Effect: "Allow" Action: "sns:Publish" Resource: "*" # CFnスタックを作成する - Sid: createStack Effect: "Allow" Action: - "sqs:*" - "cloudformation:CreateStack" - "cloudformation:DescribeStacks" - "s3:GetObject" Resource: "*" # S3バケットを作成する - Sid: createBucket Effect: "Allow" Action: - "s3:CreateBucket" - "s3:PutBucketTagging" Resource: "*"
SSMドキュメント
以下のような SSMドキュメントを作成しました。 ハイライト部分を適宜書き換えてください。
schemaVersion: "0.3" description: "create a new S3 bucket with approval" assumeRole: "{{AssumeRole}}" parameters: AssumeRole: description: "(Required) Automation Role." type: String default: "(先程作ったIAMロールのARN)" allowedValues: - "(先程作ったIAMロールのARN)" SnsTopic: description: "(Required) The SNS topic ARN used to send pending approval notification." type: String default: "(先程作ったSNSトピックのARN)" allowedValues: - "(先程作ったSNSトピックのARN)" TemplateURL: description: "(Required) CFn TemplateURL" type: String default: "(先程作ったCFnテンプレートの格納先 URL)" allowedValues: - "(先程作ったCFnテンプレートの格納先 URL)" StackName: description: "(Required) CFn StackName" type: String BucketName: description: "(Required) Parameter: BucketName" type: String ProjectName: description: "(Required) Parameter: ProjectName" type: String mainSteps: - name: "approve" action: "aws:approve" onFailure: Abort inputs: NotificationArn: "{{SnsTopic}}" Message: "Approval required to createStack: {{StackName}} (BucketName: {{BucketName}}, ProjectName: {{ProjectName}})" MinRequiredApprovals: 1 Approvers: - "(管理者のIAMロールARN)" - name: "createStack" action: "aws:createStack" onFailure: Abort inputs: StackName: "{{StackName}}" TemplateURL: "{{TemplateURL}}" Parameters: - ParameterKey: BucketName ParameterValue: "{{BucketName}}" - ParameterKey: ProjectName ParameterValue: "{{ProjectName}}"
これを登録していきます。
マネコンの SSMドキュメント のページに行き、 オートメーションを作成する
を選択します。
名前を適当に記入(例えば CreateNewS3BucketWithApproval
) して、
ドキュメントエディタに貼り付けてオートメーションを作成します。
SSMドキュメント詳細
作成した SSMドキュメントの内容解説です。
「SSMドキュメントの構文や SSMオートメーションで使用可能なアクションを知りたい人」向けです。 必要ない場合は次章 "検証(利用の流れ)" をご覧ください。
全体構成
schemaVersion: "0.3" description: "create a new S3 bucket with approval" assumeRole: "{{AssumeRole}}" parameters: AssumeRole: description: "(Required) Automation Role." type: String default: "(先程作ったIAMロールのARN)" allowedValues: - "(先程作ったIAMロールのARN)" (略) mainSteps: - name: "approve" action: "aws:approve" (略) - name: "createStack" action: "aws:createStack" (略)
大枠部分の構文は以下ドキュメントを読めば分かります。
schemaVersion は使用するスキーマバージョンです。
Automation
ドキュメントは 0.3
を指定する必要があります。
description はドキュメントの説明です。
assumeRole は SSMオートメーションの実行ロールを指定します。
後述のパラメータ AssumeRole
を参照しています。
parameters でパラメータを定義します。おおよそ CFnのパラメータと同じような使い方です。
"{{ParameterName}}"
といった形で他セクションで参照できます。
mainSteps で実行するアクションを連ねていきます。 「承認→作成」フローを書くセクションです。詳細は後述。
mainSteps#1(aws:approve
)
# "approve" ステップ - name: "approve" # 実行するアクション action: "aws:approve" # 失敗時の行動。Abotr(中止), Continue(続行), step:xxx(別ステップへ遷移) onFailure: Abort inputs: # 通知先SNSトピック NotificationArn: "{{SnsTopic}}" # メッセージ Message: "Approval required to createStack: {{StackName}} (BucketName: {{BucketName}}, ProjectName: {{ProjectName}})" # 必要な承認の最小数 MinRequiredApprovals: 1 # 承認できるプリンシパルのリスト Approvers: - "(管理者のIAMロールARN)"
まず SSMオートメーションで実行可能なアクションのリファレンスは以下リンクから辿れます。
最初のステップでは aws:approve を使います。 指定した承認者から、必要数の承認を得られた場合に次のステップに進めます。
必要に応じて MinRequiredApprovals
(必要な承認の最小数) や
Approvers
(承認できるプリンシパルのリスト)を変更しましょう。
mainSteps#2(aws:createStack
)
# "createStack" ステップ - name: "createStack" # 実行するアクション action: "aws:createStack" # 失敗時の行動。Abotr(中止), Continue(続行), step:xxx(別ステップへ遷移) onFailure: Abort inputs: # スタック名 StackName: "{{StackName}}" # テンプレートURL TemplateURL: "{{TemplateURL}}" # CFnパラメータ Parameters: - ParameterKey: BucketName ParameterValue: "{{BucketName}}" - ParameterKey: ProjectName ParameterValue: "{{ProjectName}}"
このステップでは aws:createStack を使います。 テンプレートを指定して新しい CFnスタックを作成するアクションです。
検証(利用の流れ)
[開発者] オートメーションを実行する
開発者は SSMのマネコンから、作成したドキュメントを選択します。
"オートメーションを実行する" を選択します。
デフォルトの "シンプルな実行" を選択したままで、 以下のようにパラメータを入力します。 AssumeRole, SnsTopic, TemplateURL は固定値にしているので、 開発者はスタック名と CFnパラメータ(作成したバケットの名前とプロジェクト名)を入力します。
内容確認して "実行" します。
[管理者] 承認する
SNS経由で管理者へメール通知されます。以下のような内容です。
Approve のリンクへ移動します。以下のような承認/拒否画面になります。
メッセージからリクエストされた情報(スタック名やパラメータ)を確認し、 承認を選択して "送信" します。
スタック作成を確認
スタック作成が成功する場合は、以下のように全ステップ "成功" となります。
CFnスタック、および スタックリソース(S3バケット)も確認できました。
おわりに
シンプルですが SSMオートメーションを使った CFnスタック展開の承認フローを作ってみました。
最近登場した Systems Manager Change Manager (変更管理のプロセス、承認フロー作成の機能) の 実態は オートメーションです。 Change Manager を触る前に、 今回みたいにオートメーションを軽く触ることでスムーズに理解が進むのではないでしょうか。
参考
- AWS Documents
- AWS Systems Manager ドキュメント - AWS Systems Manager
- AWS Systems Manager オートメーション - AWS Systems Manager
- SSM ドキュメントの構文 - AWS Systems Manager
- Systems Manager オートメーションアクションのリファレンス - AWS Systems Manager
- aws:approve – 手動承認のためにオートメーションを一時停止する - AWS Systems Manager
- aws: createStack – AWS CloudFormation スタックを作成する - AWS Systems Manager
- DevelopersIO